﻿/**
 * Created by xjchen on 2020-03-20.
 * */

#ifndef MIDDLEWARE_ETHERNETWRITER_H
#define MIDDLEWARE_ETHERNETWRITER_H


#include "DeviceWriter.h"
#include "EthernetReader.h"
#include "AutoDetectWriter.h"
#include "Wrapper.h"
#include "Function.h"

class TCPClient;

class UDPClient;

class EthernetWriter : public DeviceWriter {
public:
    ~EthernetWriter();

    EthernetWriter(TransportProtocol protocol, std::string ip, uint16_t port, bool isBlocking,
                   int reconnectDelay = 10000);

    int64_t onWrite(char *buffer, int64_t len) override;

    /**
     * 返回socket描述符，一般在 setPostSetupAction() 中使用
     * 
     * @return SOCKET, 无效时返回INVALID_SOCKET
     */
    SOCKET getSocket();

    void changeTarget(std::string ip, uint16_t port);

    void setOwner(AutoDetectWriter *writer);

    void setupConnection() override;

    /**
     * 设置 setupConnection() 完成后动作
     * 
     * 传入的函数应同时在 AppDelegate::onConfigure() 中使用 REGISTER_FUNCTIONS() 进行注册
     */
    FLOW_API void setPostSetupAction(void (*func)(EthernetWriter *));

    void stop() override;

    /**
     * 设置组播报文的发送接口
     * 
     * @param intf 发送接口的IP地址
     * 
     * @return 
     *       0: 成功
     *      -1: 失败
     */
    FLOW_API int setMulticastIF(const std::string intf);

    /**
     * 设置组播报文的TTL
     * 
     * @param ttl 默认为1
     * 
     * @return 
     *       0: 成功
     *      -1: 失败
     */
    FLOW_API int setMulticastTTL(unsigned int ttl);

private:
    friend class RefreshDeviceConnect;

    TCPClient *tcpClient = 0;
    UDPClient *udpClient = 0;
    bool isValid;
    AutoDetectWriter *owner = 0;
    Function postSetupAction;
    std::string mcIntf = "";
    unsigned int mcTTL = 0;
};


#endif /** MIDDLEWARE_ETHERNETWRITER_H */
